/**
 * 
 */
package com.manthano.util.validation;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Dell
 */
@SuppressWarnings("javadoc")
public class FieldValidationUtil
{

	/**
	 * @param collection
	 * @return boolean
	 */
	@SuppressWarnings("rawtypes")
	public static boolean isCollectionEmpty(Collection collection)

	{
		if ((collection != null) && (!collection.isEmpty()))

		{
			return false;
		}
		return true;
	}

	/**
	 * @param collection
	 * @return boolean
	 */
	public static boolean isArrayEmpty(Object[] collection)

	{
		if ((collection != null) && (collection.length > 0))

		{
			return false;
		}
		return true;
	}

	/**
	 * @param str
	 * @return boolean
	 */
	public static boolean isBlank(String str)
	{
		if ((str == null) || (str.trim().equals("")))

		{
			return true;
		}
		return false;
	}

	/**
	 * @param mailHost
	 * @return boolean
	 */
	public static boolean isMailHostValid(String mailHost)

	{
		String regex = "^(([a-z]|[a-z0-9][a-z0-9]*[a-z0-9])[\\.|\\-])*([a-z]|[a-z0-9][a-z0-9]*[a-z0-9])$";
		Pattern pattern = Pattern.compile(regex);
		if (null == mailHost)

		{
			return true;
		}
		Matcher matcher = pattern.matcher(mailHost);
		if (matcher.matches())

		{
			return true;
		}

		return false;
	}

	/**
	 * @param mailHostPort
	 * @return boolean
	 */
	public static boolean isMailHostPortValid(String mailHostPort)

	{
		int port = 0;
		if (null == mailHostPort)

		{
			return true;
		}

		try
		{
			port = Integer.parseInt(mailHostPort);
		}
		catch (NumberFormatException e)

		{
			return false;
		}
		if ((port < 9999) && (port > 0))

		{
			return true;
		}

		return false;
	}

	/**
	 * @param str
	 * @param min
	 * @param max
	 * @return boolean
	 */
	public static boolean inRange(String str, int min, int max)

	{
		if ((str.length() >= min) && (str.length() <= max))

		{
			return true;
		}
		return false;
	}

	public static boolean isNumber(String str)

	{
		try
		{
			Long.parseLong(str);
		}
		catch (NumberFormatException excp)

		{
			return false;
		}
		return true;
	}

	public static String getString(String str, int length)

	{
		if ((str != null) && (str.length() > length))

		{
			return str.substring(0, length);
		}
		return str;
	}

	public static boolean isCompanyNameValid(String companyName)

	{
		if (isBlank(companyName))

		{
			return false;
		}
		if (companyName.trim().length() > 75)

		{
			return false;
		}

		return true;
	}

	public static boolean isUserNameValid(String userName)

	{
		if (isBlank(userName))

		{
			return false;
		}
		if (userName.trim().length() > 75)

		{
			return false;
		}

		return true;
	}

	public static boolean isDisplayNameValid(String displayName)

	{
		if (isBlank(displayName))

		{
			return false;
		}
		if (displayName.trim().length() > 13)

		{
			return false;
		}

		return true;
	}

	public static boolean isAddressValid(String address)

	{
		if (isBlank(address))

		{
			return false;
		}
		if (address.trim().length() > 150)

		{
			return false;
		}

		return true;
	}

	public static boolean isCityValid(String cityName)

	{
		if (isBlank(cityName))

		{
			return false;
		}
		if (cityName.trim().length() > 75)

		{
			return false;
		}

		return true;
	}

	public static boolean isStateValid(String stateName)

	{
		if (isBlank(stateName))

		{
			return false;
		}
		if (stateName.trim().length() > 75)

		{
			return false;
		}

		return true;
	}

	public static boolean isProductNameValid(String productName)

	{
		String productPattern = "^[a-zA-Z0-9_ ]*$";
		if (isBlank(productName))

		{
			return false;
		}
		if (productName.trim().length() > 35)

		{
			return false;
		}

		if (!productName.matches(productPattern))

		{
			return false;
		}

		return true;
	}

	public static boolean isURLValid(String productURL)

	{
		if (isBlank(productURL))

		{
			return false;
		}
		if (productURL.trim().length() > 1500)

		{
			return false;
		}

		return true;
	}

	public static boolean isLocationNameValid(String locationName)

	{
		if (isBlank(locationName))

		{
			return false;
		}
		if (locationName.trim().length() > 75)

		{
			return false;
		}

		return true;
	}

	public static boolean isZipCodeValid(String zipCode)

	{
		if (isBlank(zipCode))

		{
			return false;
		}
		String zipCodePattern1 = "\\d{5}-\\d{4}";
		String zipCodePattern2 = "[a-zA-Z\\d]*";
		if (zipCode.length() == 10)

		{
			if (!zipCode.matches(zipCodePattern1))

			{
				return false;
			}
		}
		else if (zipCode.length() < 10)

		{
			if (!zipCode.matches(zipCodePattern2))

			{
				return false;
			}
		}
		else
		{
			return false;
		}
		return true;
	}

	public static boolean isTelephoneNumberValid(String telephoneNo)

	{
		if (isBlank(telephoneNo))

		{
			return false;
		}
		String expression = "^\\+{0,1}(?:[0-9-#()] ?){6,22}[0-9-#()]$";
		if (!isBlank(telephoneNo))

		{
			if (!telephoneNo.matches(expression))

			{
				return false;
			}

		}

		return true;
	}

	public static boolean isExtensionValid(String extension)

	{
		if (isBlank(extension))

		{
			return false;
		}
		String expression = "^\\+{0,1}(?:[0-9-#()] ?){1,7}[0-9-#()]$";
		if (!isBlank(extension))

		{
			if (!extension.matches(expression))

			{
				return false;
			}

		}

		return true;
	}

	public static boolean isActivityNameValid(String activityName)

	{
		if (isBlank(activityName))

		{
			return false;
		}
		if (activityName.trim().length() > 40)

		{
			return false;
		}

		return true;
	}

	public static boolean isActivityGroupNameValid(String activityGroupName)

	{
		if (isBlank(activityGroupName))

		{
			return false;
		}
		if (activityGroupName.trim().length() > 40)

		{
			return false;
		}
		return true;
	}

	public static boolean isRoleNameValid(String roleName)

	{
		if (isBlank(roleName))

		{
			return false;
		}
		if (roleName.trim().length() > 40)

		{
			return false;
		}

		return true;
	}

	public static boolean isRoleDescriptionValid(String discription)

	{
		if (isBlank(discription))

		{
			return false;
		}

		discription = discription.trim();
		discription = discription.replaceAll("(\\r\\n)", "\n");
		if (discription.trim().length() > 300)

		{
			return false;
		}

		return true;
	}

	public static boolean isPasaswordLengthValid(String password)

	{
		if (isBlank(password))

		{
			return false;
		}
		if (password.trim().length() > 32)

		{
			return false;
		}

		return true;
	}

	public static boolean isLegal(String inputStr)

	{
		String illegalChars = "!@#$%^&*_+=|\\{}[]~`\"':;?/<>,.";
		for (int i = 0; i < inputStr.length(); i++)

		{
			if (illegalChars.indexOf(inputStr.charAt(i)) > -1)

			{
				return false;
			}
		}
		return true;
	}

	public static boolean isKeyValid(String key)

	{
		boolean validFlag = true;

		if (isBlank(key))

		{
			validFlag = false;
		}
		else
		{
			String keyPattern = "[a-zA-Z]+[^@!#$%+{}<>()?.,;:`~'&\"*=|\\[\\]\\^/\\\\][a-zA-Z0-9-_[\\s]]*";
			if (key.length() == 1)

			{
				if (!key.matches("[a-zA-Z]"))

				{
					validFlag = false;
				}

			}
			else if (!key.matches(keyPattern))

			{
				validFlag = false;
			}
			else if (!key.matches("\\S++(?:\\s\\S++)*+"))

			{
				validFlag = false;
			}

		}

		return validFlag;
	}

	public static boolean isEmailAddressCorrect(String emailAddress)

	{
		String regexInvalidCharacter = "([^\\\";.:\\[\\]<>()@,\\\\])";
		String regexValidCharacter = "[[\\p{L}{M}\\*]\\p{Digit}[\\p{Punct}&&[^;:\\\"\\[\\]<>(),@\\\\]]]*";
		String regexDomainPart = "@([\\w\\-]+\\.)+[A-Za-z]{2,4}$";

		String regex = regexInvalidCharacter + regexValidCharacter + regexInvalidCharacter + regexDomainPart;

		if (!emailAddress.contains("@"))

		{
			return false;
		}
		if (isSpace(emailAddress))

		{
			return false;
		}
		String localPart = emailAddress.substring(0, emailAddress.indexOf('@'));
		if ((localPart != null) && (localPart.length() > 0))

		{
			if (localPart.length() == 1)

			{
				regex = regexValidCharacter + regexDomainPart;
			}
			else if (localPart.length() == 2)

			{
				regex = regexValidCharacter + regexInvalidCharacter + regexDomainPart;
			}
		}
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(emailAddress);
		if (matcher.matches())

		{
			if (emailAddress.matches("[^.]++(?:.[^.]++)*+"))

			{
				return true;
			}

			return false;
		}

		return false;
	}

	public static String removeSpecialCharacters(String str)

	{
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < str.length(); i++)

		{
			if (((str.charAt(i) >= '0') && (str.charAt(i) <= '9'))
					|| ((str.charAt(i) >= 'A') && (str.charAt(i) <= 'z')) || (str.charAt(i) == '.')
					|| (str.charAt(i) == '_'))
			{
				sb.append(str.charAt(i));
			}
		}
		return sb.toString();
	}

	public static boolean isSpace(String parameter)

	{
		return parameter.contains(" ");
	}

	public static boolean compareIps(String ip1, String ip2)

	{
		String[] ip1Array = ip1.trim().split("\\.");
		String[] ip2Array = ip2.trim().split("\\.");

		for (int i = 0; i < ip2Array.length; i++)

		{
			if (ip1Array[i].equals("*"))
			{
				return true;
			}
			if (!ip1Array[i].equals(ip2Array[i]))
			{
				return false;
			}
		}
		return true;
	}

	public static boolean isValidReferenceIp(String ip)

	{
		if (ip.trim().lastIndexOf(".") == (ip.trim().length() - 1))
		{
			return false;
		}
		String[] ipArray = ip.split("\\.");
		if (ipArray.length > 4)

		{
			return false;
		}

		if (ip.indexOf("*") != -1)

		{
			boolean isStarFound = false;
			for (String s : ipArray)

			{
				try
				{
					if (Integer.parseInt(s) > 255)

					{
						return false;
					}

					if (isStarFound)
					{
						return false;
					}

				}
				catch (NumberFormatException e)

				{
					if (s.equals("*"))

					{
						isStarFound = true;
					}
					else
					{
						return false;
					}
				}
			}

		}
		else
		{
			if (ipArray.length == 4)

			{
				if (!validateIPAddress(ip))

				{
					return false;
				}

				return true;
			}

			return false;
		}

		return true;
	}

	public static boolean validateIPAddress(String ip)
	{
		Pattern pattern = Pattern
				.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
		Matcher matcher = pattern.matcher(ip);
		return matcher.matches();
	}

	public static boolean validateInitialsMinLength(String initials)
	{
		if (initials == null)

		{
			return false;
		}
		if (initials.length() <= 1)

		{
			return false;
		}

		return true;
	}

	public static boolean validateInitialsMaxLength(String initials)
	{
		if (initials == null)

		{
			return false;
		}
		if (initials.length() > 5)

		{
			return false;
		}

		return true;
	}

	public static boolean isUserInitialsValid(String initials)
	{
		String regex = "[\\p{L}]*";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(initials);
		if (matcher.matches())

		{
			return true;
		}

		return false;
	}

	public static boolean isTimeFormatValid(String timeFormat)
	{
		if (isBlank(timeFormat))

		{
			return false;
		}
		if ((timeFormat.equalsIgnoreCase("24 Hours")) || (timeFormat.equalsIgnoreCase("12 Hours")))

		{
			return true;
		}

		return false;
	}

	public static boolean isLessThanSystemDate(long longDate)

	{
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm");
		Date currDate = null;
		try
		{
			currDate = dateFormat.parse(dateFormat.format(new Date()));
		}
		catch (ParseException e)

		{
			return true;
		}

		Date date2 = new Date(longDate);

		if (currDate.compareTo(date2) > 0)

		{
			return true;
		}

		return false;
	}

	private static Calendar clearTimes(Calendar calendar)
	{
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar;
	}

	/**
	 * @param val
	 * @return String
	 */
	public static String convertSimpleDayFormat(long val)
	{
		Calendar today = Calendar.getInstance();
		today = clearTimes(today);

		Calendar yesterday = Calendar.getInstance();
		yesterday.add(Calendar.DAY_OF_YEAR, -1);
		yesterday = clearTimes(yesterday);

		Calendar last7days = Calendar.getInstance();
		last7days.add(Calendar.DAY_OF_YEAR, -7);
		last7days = clearTimes(last7days);

		Calendar last30days = Calendar.getInstance();
		last30days.add(Calendar.DAY_OF_YEAR, -30);
		last30days = clearTimes(last30days);

		if (val > today.getTimeInMillis())
		{
			return "Today";
		}
		else if (val > yesterday.getTimeInMillis())
		{
			return "Yesterday";
		}
		else if (val > last7days.getTimeInMillis())
		{
			return "Last 7 days";
		}
		else if (val > last30days.getTimeInMillis())
		{
			return "Last 30 days";
		}
		else
		{
			return "Morethan 30 days";
		}
	}
}
